﻿// -----------------------------------------------------------------------
// <copyright file="Words_Facility.cs" company="G.W. van der Vegt">
// SharpForth is inspired by JonesForthInC v1.48 and bb4wForth.
// </copyright>
// -----------------------------------------------------------------------

namespace SharpForth
{
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Collections.Generic;
    using System.Threading;

    /// <summary>
    /// This static class contains all built-in Forth Words.
    /// </summary>
    public static partial class Words
    {
        #region Facility Forth Words

        /// <summary>
        /// Returns the Current Date and Time.
        /// </summary>
        [WordName("TIME&DATE")]
        [WordSet(WordSets.FACILITY_EXT)]
        [Syntax("( -- +n1 +n2 +n3 +n4 +n5 +n6 )")]
        internal static Lazy<DictionaryEntry> TIME_AND_DATE = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("TIME&DATE", 0, delegate
              {
                  DateTime val = DateTime.Now;

                  Forth.PUSH_P_STACK(val.Second);
                  Forth.PUSH_P_STACK(val.Minute);
                  Forth.PUSH_P_STACK(val.Hour);
                  Forth.PUSH_P_STACK(val.Day);
                  Forth.PUSH_P_STACK(val.Month);
                  Forth.PUSH_P_STACK(val.Year);

              }), true);

        /// <summary>
        /// Perform a Delay in mSec.
        /// </summary>
        [WordName("MS")]
        [WordSet(WordSets.FACILITY_EXT)]
        [Syntax("( u -- )")]
        internal static Lazy<DictionaryEntry> MS = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("MS", 0, delegate
              {
                  Thread.Sleep(Forth.POP_P_STACK());

              }), true);

        /// <summary>
        /// Clears the Screen &amp; DebugView.
        /// </summary>
        [WordName("PAGE")]
        [WordSet(WordSets.FACILITY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> PAGE = new Lazy<DictionaryEntry>(
            () => new DictionaryEntry("PAGE", 0, delegate
            {
                Forth.DoOutput(Forth.CLsMarker);

                //Clear SysInternals DebugView too.
                Debug.Print(Forth.CLsMarker);

                Forth.NEXT();
            }), true
            );

        /// <summary>
        /// Returns true if we can EMIT.
        /// </summary>
        [WordName("EMIT?")]
        [WordSet(WordSets.FACILITY_EXT)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> EMIT_QUESTION = new Lazy<DictionaryEntry>(
            () => new DictionaryEntry("EMIT?", 0, delegate
            {
                //! Return that we're always ready!
                Forth.PUSH_P_STACK(Forth.FORTH_TRUE);

                Forth.NEXT();
            }), true
            );

        /// <summary>
        /// Returns true if there is input.
        /// </summary>
        [WordName("KEY?")]
        [WordSet(WordSets.FACILITY_EXT)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> KEY_QUESTION = new Lazy<DictionaryEntry>(
            () => new DictionaryEntry("KEY?", 0, delegate
            {
                //! Check Input Queue for Content.
                Forth.PUSH_P_STACK(Forth.input.Count > 0 ? Forth.FORTH_TRUE : Forth.FORTH_FALSE);

                Forth.NEXT();
            }), true
            );

        /// <summary>
        /// Positions the cursor.
        /// </summary>
        [WordName("AT-XY")]
        [WordSet(WordSets.FACILITY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> AT_X_Y = new Lazy<DictionaryEntry>(
            () => new DictionaryEntry("AT-XY", 0, delegate
            {
                //! Check Input Queue for Content.
                Int32 y = Forth.POP_P_STACK();
                Int32 x = Forth.POP_P_STACK();

                Forth.DoOnGotoXY(x, y);

                Forth.NEXT();
            }), true
            );
        #endregion Facility Forth Words
    }
}
